﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COP.Objects.Config;
using System.Xml;
using COP.Objects;
using COP.Providers;
using COP.Extractors;
using System.Collections;
using COP.Objects.Maps;

namespace COP.Readers
{

    public class XMLConfigReader : IConfigReader
    {
        IConfigProvider provider =null;
        IExtractor extractor = null;

        XmlNodeList list = null;
        XmlDocument doc = null;

        public XMLConfigReader() : this(new XMLConfigProvider(),new XMLExtractor()) { }

        public XMLConfigReader(IExtractor extractor) : this(new XMLConfigProvider(),extractor) { }

        public XMLConfigReader(IConfigProvider provider) : this(provider, new XMLExtractor()) { }

        public XMLConfigReader(IConfigProvider provider, IExtractor extractor)
        {
            this.provider = provider;
            this.extractor = extractor;
            doc = (XmlDocument)this.provider.LoadConfig();
            list = doc.GetElementsByTagName(Constant.Config.Tag);
        }

        public ConfigBase ReadTag(string name)
        {
            ConfigBase config = null;

            foreach (XmlNode node in list)
            {

                if (node.Attributes[Constant.Config.Name].Value.ToLower() != name.ToLower())
                    continue;
                else
                    config = ReadNode(node);
                break;
            }
            return config;
        }

        private ConfigBase ReadNode(XmlNode node)
        {
            ConfigBase config = null;
            TagType type = (TagType)Enum.Parse(typeof(TagType), node.Attributes[Constant.Config.Type].Value);
            switch (type)
            {
                case TagType.Boolean:
                    config = new BooleanConfig(extractor);                    
                    break;
                case TagType.OneToOne:
                    config = new OneToOneConfig(extractor);
                    break;
                case TagType.OneToMany:
                    config = new OneToManyConfig(extractor);
                    break;
                case TagType.ManyToMany:
                    config = new ManyToManyConfig(extractor);
                    break;
                default:
                    throw new Exception(Constant.Error.InvalidType);

            }            
            config.Source = SourceType.XML;
            config.Create(node.ChildNodes[0]);
            return config;
        }

        public IList<ConfigBase> Read()
        {
            IList<ConfigBase> configlist = new List<ConfigBase>();
            foreach (XmlNode node in list)
            {
                configlist.Add(ReadNode(node));
            }
            return configlist;
        }
    }


   


}